import { goTo } from '@/modules/move'
import { hugeCrowdTask } from '../types'
import { getFreeSpace, isNearEdge } from '@/utils/position'
import { isEnemy } from '@/utils/war'

/**
 * 人海战术工作
 */
export const hugeCrowdWork = (creeps: Creep[], task: hugeCrowdTask) => {
    creeps = creeps.filter((creep) => !creep.spawning)

    const targetRoomName = task.roomName
    // 集合旗帜
    const flag = Game.flags[`${targetRoomName}_crowd_gather`]
    if (!flag) return

    // 目标房间相对于旗帜房间的方向
    const centerPos = new RoomPosition(25, 25, targetRoomName)
    const direction = flag.pos.getDirectionTo(centerPos) as 1 | 3 | 5 | 7
    // 旗帜旁边的空闲点位
    let freePos: RoomPosition[] = []
    task.range = task.range || 8

    // 能否总攻
    if (!task.canAttack) {
        task.canAttack = creeps.every((creep) => creep.memory.ready) && task.spawnComplete
    }

    creeps.forEach((creep, index) => {
        delete creep.memory.ready
        if (!task.canAttack) {
            if (creep.pos.roomName !== flag.pos.roomName) {
                goTo(creep, flag.pos, {
                    avoidRooms: [targetRoomName],
                    maxOps: 8000,
                })
            } else {
                while (freePos.length < 100) {
                    freePos = getFreeSpace(flag.pos, { range: task.range, direction }).filter(
                        (pos) => !isNearEdge(pos, 2),
                    )
                }
                const standPos = freePos[index]
                if (!creep.pos.isNearTo(standPos)) {
                    if (Math.random() < 0.3) return
                    goTo(creep, standPos, { range: 0, maxRooms: 1 })
                } else {
                    creep.memory.ready = true
                }
            }
        }
    })

    if (!task.canAttack) return

    creeps.forEach((creep) => {
        const targetRoom = Game.rooms[targetRoomName]

        if (!targetRoom) {
            creep.moveTo(centerPos, { range: 20 })
            return
        }

        if (!targetRoom.structures) {
            targetRoom.structures = targetRoom.find(FIND_STRUCTURES)
        }
        if (!targetRoom.enemys) {
            targetRoom.enemys = targetRoom.find(FIND_HOSTILE_CREEPS).filter((e) => isEnemy(e))
        }
        const tower = targetRoom.structures.find((s) => s.structureType === 'tower') as StructureTower
        const spawn = targetRoom.structures.find((s) => s.structureType === 'spawn') as StructureSpawn

        if (creep.memory.taskId === 'move') {
            if (!tower) {
                creep.suicide()
                return
            }
            if (!creep.pos.isNearTo(tower)) {
                creep.moveTo(tower)
            }
            return
        } else if (creep.memory.taskId === 'carry') {
            if (!tower) return
            if (!creep.pos.isNearTo(tower)) {
                creep.moveTo(tower)
            } else if (tower.store['energy'] > 0) {
                if (creep.store['energy'] <= 0) {
                    creep.withdraw(tower, 'energy')
                } else {
                    creep.drop('energy')
                }
            }
        } else if (creep.memory.taskId === 'attack') {
            let target: Structure | Creep | null = spawn
            if (!target) {
                target = creep.pos.findClosestByRange([
                    ...targetRoom.enemys,
                    ...targetRoom.structures.filter((s) => s.hits),
                ])
            }
            if (!target) {
                creep.suicide()
                return
            }
            if (!creep.pos.isNearTo(target)) {
                creep.moveTo(target)
                return
            }
            creep.attack(target)
        }
    })
}
